package com.xju.atpgs.generator;

import javafx.scene.Parent;
import org.springframework.security.core.parameters.P;

import java.util.List;
import java.util.Random;

public class GeneticAlgorithm {
    public static Population evolvePopulation(Population fatherGroup){
        Population sonGroup=new Population(fatherGroup.getLength());
        Paper bestOne=fatherGroup.getBest();
        sonGroup.setPaper(0,bestOne);
        for (int i=1;i<sonGroup.getLength();i++){
            Paper mother=select(fatherGroup);
            Paper father=select(fatherGroup);
            while (fatherGroup.getPapers().indexOf(mother)==fatherGroup.getPapers().indexOf(father)){
                father=select(fatherGroup);
            }
            Paper child=crossover(mother,father);
            sonGroup.setPaper(i,child);
        }
        Paper tmpPaper;
        for (int i=1;i<sonGroup.getLength();i++){
            tmpPaper=sonGroup.getPaper(i);
            mutate(tmpPaper);
            tmpPaper.updateParameter();
        }

        return sonGroup;
    }

    public static Paper crossover(Paper mother, Paper father){
        GeneticParameter geneticParameter=mother.getGeneticParameter();
        Paper child=new Paper(geneticParameter);
        Random random=new Random();
        int s1=random.nextInt(geneticParameter.getTotalNumber());
        int s2=random.nextInt(geneticParameter.getTotalNumber());
        int startPos=s1<s2?s1:s2;
        int endPos=s1<s2?s2:s1;
        for (int i=startPos;i<endPos;i++){
            child.saveQuestion(i,mother.getQuestionList().get(i));
        }
        for (int i=0;i<startPos;i++){
            child.saveQuestion(i,father.getQuestionList().get(i));
        }
        for (int i=endPos;i<father.getQuestionList().size();i++){
            child.saveQuestion(i,father.getQuestionList().get(i));
        }
        child.updateRepeat();
        child.updateParameter();
        return child;
    }

    public static  void mutate(Paper paper){
        GeneticParameter geneticParameter=paper.getGeneticParameter();
        Random random=new Random();
        double j=random.nextDouble();
        Integer index;
        for (int i=0;i<paper.getQuestionList().size();i++){
            if(j<geneticParameter.getMUTATION_P()){
                index=randomQuestion(paper,i);
                paper.saveQuestion(i,index);
            }
        }
        paper.updateParameter();
    }

    //对应题型试题随机选一个替换
    public static Integer randomQuestion(Paper paper,int position){
        int index=0,i=0;
        Random random=new Random();
        GeneticParameter geneticParameter=paper.getGeneticParameter();
        int index1 = geneticParameter.getChoiceNum();
        int index2 =  geneticParameter.getChoiceNum()+ geneticParameter.getJudgeNum();
        int index3 =  geneticParameter.getChoiceNum()+ geneticParameter.getJudgeNum() + geneticParameter.getFillingNum();
        int index4 =  geneticParameter.getChoiceNum()+ geneticParameter.getJudgeNum() + geneticParameter.getFillingNum() + geneticParameter.getShortAnswerNum();
        int index5 =  geneticParameter.getChoiceNum()+ geneticParameter.getJudgeNum() + geneticParameter.getFillingNum() + geneticParameter.getShortAnswerNum() + geneticParameter.getSolveNum();
        if(position<index1){
            List<Integer> choice=paper.getChoice();
            i=position;
            do{
                index=random.nextInt(paper.getGeneticParameter().getChoiceQuestion().size());
            }while (choice.contains(index));
        }else if(position<index2){
            List<Integer> judge=paper.getJudge();
            i=position;
            do{
                index=random.nextInt(paper.getGeneticParameter().getJudgeQuestion().size());
            }while (judge.contains(index));
        }else if(position<index3){
            List<Integer> filling=paper.getFilling();
            i=position;
            do{
                index=random.nextInt(paper.getGeneticParameter().getFillingQuestion().size());
            }while (filling.contains(index));
        }else if(position<index4){
            List<Integer> shortAnswer=paper.getShortAnswer();
            i=position;
            do{
                index=random.nextInt(paper.getGeneticParameter().getShortAnswerQuestion().size());
            }while (shortAnswer.contains(index));
        }else if(position<index5){
            List<Integer> solve=paper.getSolve();
            i=position;
            do{
                index=random.nextInt(paper.getGeneticParameter().getSolveQuestion().size());
            }while (solve.contains(index));
        }
        return index;
    }

    public static Paper select(Population population){
        Population group=new Population(5);
        Random random=new Random();
        int index=0;
        for (int i=0;i<5;i++){
            index=random.nextInt(population.getLength());
            Paper paper=population.getPaper(index);
            group.setPaper(i,paper);
        }
        Paper bestOne=group.getBest();
        return bestOne;
    }
}
